package com.yy.main.app.web;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.yy.kit.collections.YYMapKits;
import com.yy.kit.io.YYIOKits;
import com.yy.kit.log.YYLogKits;
import com.yy.main.app.service.remote.IImagesRemoteService;
import com.yy.main.app.web.base.CommonController;
import com.yy.pojo.image.TImages;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.Map;

/**
 * <p>
 * 存储图片的表 前端控制器
 * </p>
 *
 * @author 杨阳
 * @since 2017-09-07
 */
@Controller
@RequestMapping("/images")
@Api(value = "存储图片的前端控制器", tags = {"图片操作controller"})
public class ImagesController extends CommonController {

    @Autowired
    private IImagesRemoteService iImagesRemoteService;
    @Resource(name = "restTemplate")
    private RestTemplate restTemplate;
    //远程图片上传地址
    @Value("${images.remote.url}")
    private String imagesRemoteUrl;
    @Value("${file.local.address}")
    private String fileLocalAddress;

    /**
     * <p>
     * 上传bug图片的方法,副文本编辑器使用
     * </p>
     *
     * @param file 上传后的文件
     * @return { "code": 0 //0表示成功，其它失败 ,"msg": "" //一般上传失败后返回 ,"data": { "src":
     * "图片路径" ,"title": "图片名称" } }
     * @author 杨阳
     * @since 2017年9月6日
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ApiOperation(value = "上传图片", httpMethod = "POST", notes = "上传图片，先判断图片的md5，如果表中已经存在，直接返回就可以，如果不存在，再上传，以二进制方式存储在数据库中")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "上传的文件", required = true, paramType = "form")
    })
    @ResponseBody
    @HystrixCommand(fallbackMethod = "uploadImageFallbackMethod")
    public Map<String, Object> uploadImage(@RequestParam("file") MultipartFile file, HttpSession session) {
        //先将文件存储到本地
        String fileName = file.getOriginalFilename();

        YYLogKits.info(ImagesController.class, "文件名称 ：{}", fileName);

        File targetFile = new File(fileLocalAddress, fileName);

        try {
            file.transferTo(targetFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        File localFile = new File(fileLocalAddress + "/" + fileName);
        FileSystemResource resource = new FileSystemResource(localFile);
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<String, Object>();
        param.add("file", resource);

        HttpHeaders requestHeaders = new HttpHeaders();

        requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(param, requestHeaders);

        ResponseEntity<Map> response = restTemplate.exchange("http://images-server/images/uploadimage", HttpMethod.POST, requestEntity, Map.class);

        Map<String, Object> map = response.getBody();

        //调用接口以后就删除了，不管是否成功，这个只是一个临时文件
        localFile.delete();

        return map;
    }

    /**
     * <p>
     * 调用远程上传图片服务，失败后的回调方法
     * </p>
     *
     * @return {@link Map<String, Object>}
     * @author 杨阳
     * @since 2017年11月13日
     */
    private Map<String, Object> uploadImageFallbackMethod() {
        Map<String, Object> map = YYMapKits.createHashMap();
        map.put("success", Boolean.FALSE);
        map.put("msg", "调用远程服务失败，请重试!");
        return map;
    }

    /**
     * <p>
     * 从数据库中获取到图片，显示在页面上
     * </p>
     *
     * @param id       图片id
     * @param response {@link HttpServletResponse}
     * @author 杨阳
     * @since 2017年9月7日
     */
    @RequestMapping(value = "/getimg/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "从数据库中获取到图片，显示在页面上", httpMethod = "GET", notes = "从数据库中获取到图片，显示在页面上,以流的方式写出")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "图片ID", required = true, paramType = "path")
    })
    @HystrixCommand(fallbackMethod = "getImageFallbackMethod")
    public void getImage(@PathVariable("id") String id, HttpServletResponse response) {
        response.setContentType("image/jpeg");
        response.setCharacterEncoding("UTF-8");
        YYLogKits.info(ImagesController.class, "┌───────────────────────────────────────────────────────────────────────────┐");
        YYLogKits.info(ImagesController.class, "├图片id:{} ", id);
        TImages images = iImagesRemoteService.getImage(id);

        InputStream in = null;
        try {
            OutputStream outputSream = response.getOutputStream();
            in = new ByteArrayInputStream(images.getImage());
            int len;
            byte[] buf = new byte[1024];
            while ((len = in.read(buf, 0, 1024)) != -1) {
                outputSream.write(buf, 0, len);
            }
        } catch (IOException e) {
            YYLogKits.printException(this.getClass(), e.getMessage());
        } finally {
            YYIOKits.close(in);
        }
        YYLogKits.info(ImagesController.class, "├图片md5:{} ", images.getMd5());
        YYLogKits.info(ImagesController.class, "└───────────────────────────────────────────────────────────────────────────┘");
    }
}
